package sqladapter;

import java.util.HashMap;
import java.util.Map;

import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class SQLAdapter 
{	
	public final static String XML_NODE_NAME_FIELDS = "fields";
	public final static String XML_NODE_NAME_KEYS = "keys";
	public final static String XML_NODE_NAME_FIELD = "field";
	public final static String XML_NODE_NAME_TABLE = "table";
	public final static String XML_NODE_NAME_BROWSER = "browser";
	public final static String XML_NODE_NAME_ACTIONS = "actions";
	public final static String XML_NODE_NAME_VIEWS = "viewFields";
	public final static String ATTRIB_TABLE_NAME = "tableName";
	public final static String ATTRIB_VIEW_NAME = "viewName";
	public final static String ATTRIB_ACTION_CLASS = "class";
	public final static String ATTRIB_ACTION_ICON = "icon";
	public final static String ATTRIB_ACTION_ADMINONLY = "adminOnly";
	public final static String ATTRIB_ACTION_TOOLTIPTEXT = "toolTipText";
	
	
	
	private String selectQuery;
	private String tableName;
	private String viewName;
	
	private HashMap<String,SQLFieldAttributes> fields;
	private HashMap<String,SQLFieldAttributes> keys;
	private HashMap<String, SQLFieldAttributes> views;
	
	public SQLAdapter( String xmlFilePath) throws Exception
	{
		selectQuery = "";
		DOMParser xmlparser = new DOMParser(); 
		xmlparser.parse(xmlFilePath);
		Document doc = xmlparser.getDocument(); 
		
		NodeList table=doc.getElementsByTagName(SQLAdapter.XML_NODE_NAME_TABLE);
		Element tableElem = (Element)table.item(0);

		tableName = tableElem.getAttribute(SQLAdapter.ATTRIB_TABLE_NAME);
		viewName = tableElem.getAttribute(ATTRIB_VIEW_NAME);	
				
		table=tableElem.getElementsByTagName(SQLAdapter.XML_NODE_NAME_BROWSER);
		tableElem = (Element)table.item(0);		
		if(!viewName.equals(""))
			loadViews(tableElem);
		loadFields(tableElem);	
		loadKeys(tableElem);
	}
	private void loadFields(Element tableElem) throws Exception
	{
		fields = new HashMap<String, SQLFieldAttributes>();
		loadFields(tableElem, SQLAdapter.XML_NODE_NAME_FIELDS,fields);
	}
	private void loadKeys(Element tableElem) throws Exception
	{
		keys = new HashMap<String, SQLFieldAttributes>();
		loadFields(tableElem, SQLAdapter.XML_NODE_NAME_KEYS,keys);
	}
	
	private void loadViews(Element  tableElem_) throws Exception
	{
		views = new HashMap<String, SQLFieldAttributes>();
		loadFields(tableElem_, SQLAdapter.XML_NODE_NAME_VIEWS, views);
	}
	
	/**
	 * 
	 * @param tableElem dokument  z ktorego beda czytane dane
	 * @param nodeName nazwa glownego wazla
	 * @param fieldsHashTable lista w ktorej beda umieszczane wczytane fieldy
	 * @throws Exception 
	 */
	private void loadFields(Element tableElem,String nodeName, HashMap<String, SQLFieldAttributes> fieldsHashTable) throws Exception
	{
		
		NodeList list = tableElem.getElementsByTagName(nodeName);
						
		Element element = (Element)list.item(0);
		if(element == null)
		{
			return;
		}
		NodeList fieldsList = element.getElementsByTagName(SQLAdapter.XML_NODE_NAME_FIELD);
		for(int j=0;j<fieldsList.getLength();++j)
		{
			Element field = (Element)fieldsList.item(j);				
			
			String fieldName = field.getAttribute(SQLFieldAttributes.ATTRIBUTE_FIELD_NAME);
			String fieldType = field.getAttribute(SQLFieldAttributes.ATTRIBUTE_FIELD_TYPE);
			String fieldVisible = field.getAttribute(SQLFieldAttributes.ATTRIBUTE_FIELD_VISIBLE);
			String fieldAllias = field.getAttribute(SQLFieldAttributes.ATTRIBUTE_FIELD_ALLIAS);
			String fieldFunc = field.getAttribute(SQLFieldAttributes.ATTRIBUTE_FIELD_FUNC);
			
			SQLFieldAttributes fieldAttributes = new SQLFieldAttributes(fieldName,fieldType,fieldVisible,fieldAllias,fieldFunc);
			fieldsHashTable.put(field.getAttribute(SQLFieldAttributes.ATTRIBUTE_FIELD_NAME), fieldAttributes);
		}
	}
	
	public String getTableName()
	{
	 return tableName;	
	}
	
	public String getSelectVisibleQuery()
	{
		if(!selectQuery.equals(""))
			return selectQuery;
		
		StringBuilder queryBuilder = new StringBuilder("");
		Object[] fieldKeys= fields.keySet().toArray();
		
		queryBuilder.append(" SELECT ");
		
		int j=0;
		String key;
		do
		{
			key =fieldKeys[j].toString();
			++j;
		}while(!fields.get(key).getFieldVisible().equals(SQLFieldAttributes.TRUE));
		
		queryBuilder.append(" " + fields.get(key).getFieldName()+ " as '" +fields.get(key).getFieldAllias()+"'");			
			
		for(int i=j;i<fieldKeys.length;++i)
		{
			key =fieldKeys[i].toString();
			if(fields.get(key).getFieldVisible().equals(SQLFieldAttributes.TRUE))
			{
				queryBuilder.append(" , " + fields.get(key).getFieldName()+ " as '" +fields.get(key).getFieldAllias()+"'");				
			}			
		}
		
		if(viewName.equals(""))
			queryBuilder.append(" FROM " + tableName);
		else
		{
			j=0;
			fieldKeys= views.keySet().toArray();
			key =fieldKeys[j].toString();
			while(!views.get(key).getFieldVisible().equals(SQLFieldAttributes.TRUE))
			{
				++j;
				key =fieldKeys[j].toString();				
			}
			
			for(int i=j;i<fieldKeys.length;++i)
			{
				key =fieldKeys[i].toString();
				if(views.get(key).getFieldVisible().equals(SQLFieldAttributes.TRUE))
				{
					queryBuilder.append(" , " + views.get(key).getFieldName()+ " as '" +views.get(key).getFieldAllias()+"'");				
				}			
			}
			
			queryBuilder.append(" FROM " + viewName);
		}
		
		return queryBuilder.toString();	
	}
	
	public String getSelectAllQuery()
	{
		if(!selectQuery.equals(""))
			return selectQuery;
		
		StringBuilder queryBuilder = new StringBuilder("");
		Object[] fieldKeys= fields.keySet().toArray();
		
		queryBuilder.append(" SELECT ");
		
		String key =fieldKeys[0].toString();
		
		queryBuilder.append(" " + fields.get(key).getFieldName()+ " as '" +fields.get(key).getFieldAllias()+"'");			
				
		for(int i=1;i<fieldKeys.length;++i)
		{
			key =fieldKeys[i].toString();			
			queryBuilder.append(" , " + fields.get(key).getFieldName()+ " as '" +fields.get(key).getFieldAllias()+"'");									
		}
		if(viewName.equals(""))
			queryBuilder.append(" FROM " + tableName);
		else
		{
			fieldKeys= views.keySet().toArray();
			
			for(int i=0; i<fieldKeys.length; ++i)
			{
				key =fieldKeys[i].toString();			
				queryBuilder.append(" , " + views.get(key).getFieldName()+ " as '" +views.get(key).getFieldAllias()+"'");									
			}
			
			queryBuilder.append(" FROM " + viewName);
			System.out.println(queryBuilder.toString());
		}		

		
		return queryBuilder.toString();	
	}
	
	
	/**
	 * 
	 * @return < <br>
	 * 			<b>string</b> nazwa pola jak w bazie <br>
	 * 			<b>SQLFieldAttributes</b> jego atrybuty jak w xmlu <br>
	 * 			>
	 */
	public Map<String,SQLFieldAttributes> getKeys()
	{
		return keys;
	}
	/**
	 * 
	 * @return < <br>
	 * 			<b>string</b> nazwa pola jak w bazie <br>
	 * 			<b>SQLFieldAttributes</b> jego atrybuty jak w xmlu <br>
	 * 			>
	 */
	public Map<String,SQLFieldAttributes> getFields()
	{		
		return fields;
	}
	
	/**
	 * zwroci pola zadeklarowane w xmlu jako viewFileds
	 * @return
	 */
	public Map<String,SQLFieldAttributes> getViewFields()
	{
		return views;
	}
}
